﻿using System;
using System.IO;
using System.Linq;
using System.Web;
using Ant.Interface.Environment;
using Ant.Interface.GlobalInfo;
using Ant.Interface.Mef;
using Ant.Interface.Mef.Controller;

namespace Ant.WarmupStarter
{
    public class Starter
    {
        #region"Field"

        private static readonly Starter _instance = new Starter();

        #endregion

        #region "Property"

        /// <summary>
        /// 启动对象实例。
        /// </summary>
        public static Starter Instance
        {
            get { return _instance; }
        }

        #endregion

        #region "Constructor"

        private Starter()
        {
        }

        #endregion "Constructor"

        #region "Event"

        /// <summary>
        /// 应用程序开始。
        /// </summary>
        /// <param name="application"></param>
        public void OnApplicationStart(HttpApplication application)
        {
            using (var mefController = MefFactory.GetInstance(MefControllerEnum.Host))
            {
                LoadCommonParts(mefController);
                mefController.ConventionBuilder.ForTypesDerivedFrom<IAntHost>().ExportInterfaces();
                mefController.CreateContainer();
                var antHosts = mefController.Gets<IAntHost>().ToList();
                antHosts.ForEach(antHost => antHost.HostStarting());
                try
                {
                    ApplicationStart();
                }
                catch (Exception)
                {
                    throw;
                }
                antHosts.ForEach(antHost => antHost.HostStarted());
            }
        }

        /// <summary>
        /// 请求开始。
        /// </summary>
        /// <param name="application"></param>
        public void OnBeginRequest(HttpApplication application)
        {
        }

        /// <summary>
        /// 请求开始。
        /// </summary>
        /// <param name="application"></param>
        public void OnAcquireRequestState(HttpApplication application)
        {
        }

        /// <summary>
        /// 请求结束。
        /// </summary>
        /// <param name="application"></param>
        public void OnEndRequest(HttpApplication application)
        {
        }

        /// <summary>
        /// 发生错误。
        /// </summary>
        /// <param name="application"></param>
        public void OnError(HttpApplication application)
        {
        }

        /// <summary>
        /// 会话开始后。
        /// </summary>
        /// <param name="sender">事件源。</param>
        /// <param name="e">事件参数。</param>
        public void OnSessionStart(object sender, EventArgs e)
        {
        }

        #endregion "Event"

        #region "Private Method"

        private static void ApplicationStart()
        {
            /*//选择第一个构造函数。
           Func<IEnumerable<ConstructorInfo>, ConstructorInfo> selectConstructor = constructors =>
                                                                                       {
                                                                                           var importParameters = new ArrayList();
                                                                                           var constructor = constructors.FirstOrDefault();
                                                                                           var parameters = constructor.GetParameters();
                                                                                           foreach (var parameterInfo in parameters)
                                                                                           {
                                                                                               object value;
                                                                                               MefFactory.TryGet(parameterInfo.ParameterType, out value);
                                                                                               importParameters.Add(value);
                                                                                           }
                                                                                           try
                                                                                           {
                                                                                               constructor.Invoke(importParameters.ToArray());
                                                                                           }
                                                                                           catch
                                                                                           {
                                                                                           }
                                                                                           return constructor;
                                                                                       };*/
            var mefController = MefFactory.GetInstance();
            LoadCommonParts(mefController);
            var conventionBuilder = mefController.ConventionBuilder;

            //加载单例的依赖。
            conventionBuilder.ForTypesDerivedFrom<ISingletonDependency>().Shared().ExportInterfaces();

            //加载其他需要自动依赖的部件。
            conventionBuilder.ForTypesMatching<IAutoDependency>(
                type => type.GetInterface("ISingletonDependency", false) == null).Export().ExportInterfaces();
            mefController.CreateContainer();
        }

        /// <summary>
        /// 加载通用部件。
        /// </summary>
        /// <param name="mefController">Mef控制器。</param>
        private static void LoadCommonParts(IMefController mefController)
        {
            //加载部件。
            mefController.LoadParts(Path.Combine(EnvironmentInfo.ConfigPhysicalPath, @"Mef\Config.xml"));

            //加载映射。
            mefController.LoadMappings(Path.Combine(EnvironmentInfo.ConfigPhysicalPath, @"Mef\Mappings.xml"));
        }

        #endregion
    }
}